﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crude.Common;
using System.IO;

namespace Crude.Core.Repository
{
    public class FileSystemRepository
    {
        protected const string DefaultConfiguration = "Release";

        public FileSystemRepository(string repositoryPath)
        {
            RepositoryPath = repositoryPath;
        }

        public string RepositoryPath { get; private set; }

        public ProjectObjectModel GetProjectObjectModel(ProjectDependency dependency)
        {
            DirectoryInfo assemblyDirectoryInfo =
                new DirectoryInfo(string.Format("{0}\\{1}", RepositoryPath, dependency.Name));

            if (!assemblyDirectoryInfo.Exists)
            {
                return null;
            }

            DirectoryInfo[] directoryInfos = assemblyDirectoryInfo.GetDirectories(dependency.Version, SearchOption.TopDirectoryOnly);

            if (directoryInfos.Length == 0)
            {
                return null;
            }

            DirectoryInfo versionDirectory = (from directoryInfo in directoryInfos
                                              select new
                                              {
                                                  DirectoryInfo = directoryInfo,
                                                  Version = new Version(directoryInfo.Name)
                                              }).OrderByDescending(value => value.Version).First().DirectoryInfo;

            string pomFile = string.Format("{0}\\{1}.pom.xml", versionDirectory.FullName, dependency.Name);

            return new ProjectObjectModelLoader(pomFile).Load();
        }
        
        public void UploadProject(string pomFileLocation, string sourceDirectory, ProjectObjectModel pom)
        {
            UploadProject(pomFileLocation, sourceDirectory, pom, DefaultConfiguration);
        }

        public void UploadProject(string pomFileLocation, string sourceDirectory, ProjectObjectModel pom, string configuration)
        {            
            string destDirectory = string.Format("{0}\\{1}\\{2}\\{3}", RepositoryPath, pom.Name, pom.Version, configuration);
            string destPomLocation = string.Format("{0}\\{1}\\{2}\\{1}.pom.xml", RepositoryPath, pom.Name, pom.Version);

            if (File.Exists(destPomLocation))
            {
                ProjectObjectModel currentPom = new ProjectObjectModelLoader(destPomLocation).Load();

                if (!currentPom.Equals(pom))
                {
                    throw new Exception("Cannot publish project because the current Project Object Model is diffrent than the local one," +
                        " consider increase the version or rollback the POM changes");
                }
            }
            else
            {
                FileInfo fileInfo = new FileInfo(destPomLocation);
                if (!fileInfo.Directory.Exists)
                {
                    fileInfo.Directory.Create();
                }

                File.Copy(pomFileLocation, destPomLocation);
            }

            if (Directory.Exists(destDirectory))
            {
                Directory.Delete(destDirectory, true);
            }

            FileSystemUtility.CopyFile(
                string.Format("{0}\\{1}", sourceDirectory, pom.MainOutputFile),
                string.Format("{0}\\{1}", destDirectory, pom.MainOutputFile));

            foreach (OutputFile outputFile in pom.OutputFiles)
            {
                if (outputFile.FileName != pom.MainOutputFile &&
                    (outputFile.OutputFileCondition == OutputFileCondition.Both ||
                    outputFile.OutputFileCondition.ToString() == configuration))
                {
                    string destFileName =
                        string.Format("{0}\\{1}", destDirectory, outputFile.FileName);
                    string sourceFileName =
                        string.Format("{0}\\{1}", sourceDirectory, outputFile.FileName);

                    FileSystemUtility.CopyFile(sourceFileName, destFileName);
                }
            }
        }

        public DateTime GetProjectBuildDate(ProjectObjectModel pom, string configuration)
        {
            string mainOutputLocation = string.Format("{0}\\{1}\\{2}\\{3}\\{4}", RepositoryPath, pom.Name,
                pom.Version, configuration, pom.MainOutputFile);
           
            if (!File.Exists(mainOutputLocation))
            {
                mainOutputLocation = string.Format("{0}\\{1}\\{2}\\{3}\\{4}", RepositoryPath, pom.Name,
                    pom.Version, DefaultConfiguration, pom.MainOutputFile);
            }

            FileInfo fileInfo = new FileInfo(mainOutputLocation);

            if (fileInfo.Exists)
            {
                return fileInfo.LastWriteTimeUtc;
            }
            else
            {
                return DateTime.MinValue;                 
            }               
        }


    }
}
